package middleware

import (
	"context"
	"sync"

	"github.com/ammyhaber/seckill/pkg/breaker"
)

// BreakerManagerWrapper 包装breaker.BreakerManager以提供额外功能
type BreakerManagerWrapper struct {
	manager          *breaker.BreakerManager
	customBreakers   map[string]*BreakerAdapter
	adaptiveBreakers map[string]*AdaptiveBreakerAdapter
	mutex            sync.RWMutex
}

// 创建全局包装器实例
var (
	breakerManagerWrapper     *BreakerManagerWrapper
	breakerManagerWrapperOnce sync.Once
)

// GetBreakerManagerWrapper 获取熔断器管理器包装器
func GetBreakerManagerWrapper() *BreakerManagerWrapper {
	breakerManagerWrapperOnce.Do(func() {
		// 获取基础熔断器管理器
		baseBreakerManager := GetBreakerManager()

		breakerManagerWrapper = &BreakerManagerWrapper{
			manager:          baseBreakerManager,
			customBreakers:   make(map[string]*BreakerAdapter),
			adaptiveBreakers: make(map[string]*AdaptiveBreakerAdapter),
		}
	})
	return breakerManagerWrapper
}

// RegisterBreaker 注册自定义熔断器
func (bmw *BreakerManagerWrapper) RegisterBreaker(name string, breaker *BreakerAdapter) {
	bmw.mutex.Lock()
	defer bmw.mutex.Unlock()
	bmw.customBreakers[name] = breaker
}

// RegisterAdaptiveBreaker 注册适应性熔断器
func (bmw *BreakerManagerWrapper) RegisterAdaptiveBreaker(name string, breaker *breaker.AdaptiveBreaker) {
	bmw.mutex.Lock()
	defer bmw.mutex.Unlock()
	bmw.adaptiveBreakers[name] = &AdaptiveBreakerAdapter{
		adaptiveBreaker: breaker,
	}
}

// GetBreaker 获取熔断器（优先获取自定义熔断器，如果不存在则使用基础熔断器）
func (bmw *BreakerManagerWrapper) GetBreaker(name string) (*BreakerAdapter, bool) {
	// 检查是否有自定义熔断器
	bmw.mutex.RLock()
	cb, ok := bmw.customBreakers[name]
	bmw.mutex.RUnlock()

	if ok {
		return cb, true
	}

	// 使用基础熔断器管理器获取熔断器，并用适配器包装
	advBreaker := bmw.manager.GetBreaker(name)
	if advBreaker == nil {
		return nil, false
	}

	adapter := &BreakerAdapter{
		advBreaker: advBreaker,
	}

	// 缓存适配器以便后续使用
	bmw.mutex.Lock()
	bmw.customBreakers[name] = adapter
	bmw.mutex.Unlock()

	return adapter, true
}

// BreakerAdapter 适配器，将AdvancedBreaker转换为支持ExecuteWithResult的熔断器
type BreakerAdapter struct {
	advBreaker *breaker.AdvancedBreaker
}

// Execute 执行熔断器请求
func (ba *BreakerAdapter) Execute(fn func() error) error {
	return ba.advBreaker.Execute(fn)
}

// ExecuteWithResult 执行有返回值的请求
func (ba *BreakerAdapter) ExecuteWithResult(ctx context.Context, key string, fn func() (interface{}, error)) (interface{}, error) {
	return ba.advBreaker.ExecuteWithResult(key, fn)
}

// GetState 获取熔断器状态
func (ba *BreakerAdapter) GetState() int {
	return ba.advBreaker.GetState()
}

// Reset 重置熔断器状态
func (ba *BreakerAdapter) Reset() {
	ba.advBreaker.Reset()
}

// AdaptiveBreakerAdapter 适配器，将AdaptiveBreaker转换为支持ExecuteWithResult的熔断器
type AdaptiveBreakerAdapter struct {
	adaptiveBreaker *breaker.AdaptiveBreaker
}

// Execute 执行熔断器请求
func (aba *AdaptiveBreakerAdapter) Execute(fn func() error) error {
	return aba.adaptiveBreaker.Execute(fn)
}

// ExecuteWithResult 执行有返回值的请求
func (aba *AdaptiveBreakerAdapter) ExecuteWithResult(ctx context.Context, key string, fn func() (interface{}, error)) (interface{}, error) {
	return aba.adaptiveBreaker.ExecuteWithResult(ctx, key, fn)
}

// GetState 获取熔断器状态
func (aba *AdaptiveBreakerAdapter) GetState() int {
	return int(aba.adaptiveBreaker.GetState())
}

// Reset 重置熔断器状态
func (aba *AdaptiveBreakerAdapter) Reset() {
	aba.adaptiveBreaker.Reset()
}
